package org.musicsweet.service;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.musicsweet.constant.StringConstant;
import org.musicsweet.entity.SysMenu;
import org.musicsweet.entity.SysUser;
import org.musicsweet.mapper.SysMenuMapper;
import org.musicsweet.result.ResultData;
import org.musicsweet.util.StringUtil;
import org.musicsweet.vo.ZTreeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 系统菜单Service
 * Create by yangjie on 2020/03/31
 */
@Service
@Slf4j
public class SysMenuService {

    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Autowired
    private SysUserService sysUserService;


    /**
     * 根据id查询系统菜单
     *
     * @param sysRole
     * @return
     */
    public ResultData<SysMenu> getSysMenuById(SysMenu sysRole) {
        log.info("根据id查询系统菜单:" + JSON.toJSONString(sysRole));
        if (StringUtils.isEmpty(sysRole.getId())) {
            return ResultData.createFail("id不能为空");
        }
        sysRole.setDel(StringConstant.DEL_NO);
        SysMenu data = sysMenuMapper.getSysMenuById(sysRole);
        return ResultData.successData("查询成功", data);
    }

    /**
     * 多条件查询系统菜单
     *
     * @param sysRole
     * @return
     */
    public ResultData<List<SysMenu>> getSysMenuList(SysMenu sysRole) {
        log.info("多条件查询系统菜单:" + JSON.toJSONString(sysRole));
        sysRole.setDel(StringConstant.DEL_NO);
        List<SysMenu> data = sysMenuMapper.getSysMenuList(sysRole);
        return ResultData.successData("查询成功", data);
    }


    /**
     * 添加系统菜单
     *
     * @param sysMenu
     * @param token
     * @return
     */
    @Transactional
    public ResultData addSysMenu(SysMenu sysMenu, String token) {

        SysMenu parentSysMenu = new SysMenu();
        parentSysMenu.setDel(StringConstant.DEL_NO);
        parentSysMenu.setId(sysMenu.getParentId());
        //获取到父菜单的信息
        SysMenu pMenu = sysMenuMapper.getSysMenuById(parentSysMenu);

        sysMenu.setId(StringUtil.getUUID());
        sysMenu.setCreateTime(new Date());
        //在父菜单原有的基础上+1也就是leve+1
        sysMenu.setLevel(pMenu.getLevel() + 1);
        SysUser currentUser = sysUserService.getSysUserByToken(token).getData();
        sysMenu.setCreateUserId(currentUser.getId());
        sysMenu.setDel(StringConstant.DEL_NO);
        log.info("添加系统菜单:" + JSON.toJSONString(sysMenu));
        int i = sysMenuMapper.addSysMenu(sysMenu);
        if (i > 0) {
            return ResultData.createSuccess("添加成功");
        } else {
            return ResultData.createFail("添加系统菜单失败");
        }
    }


    /**
     * 修改系统菜单
     *
     * @param sysMenu
     * @return
     */
    @Transactional
    public ResultData updateSysMenu(SysMenu sysMenu, String token) {
        if (StringUtils.isEmpty(sysMenu.getId())) {
            return ResultData.createFail("id不能为空");
        }
        if (sysMenu.getId().equals("0")) {
            return ResultData.createFail("系统菜单不能编辑");
        }
        SysUser currentUser = sysUserService.getSysUserByToken(token).getData();
        sysMenu.setUpdateUserId(currentUser.getId());
        sysMenu.setUpdateTime(new Date());
        log.info("修改系统菜单:" + JSON.toJSONString(sysMenu));
        int i = sysMenuMapper.updateSysMenu(sysMenu);
        if (i > 0) {
            return ResultData.createSuccess("修改成功");
        } else {
            return ResultData.createFail("修改系统菜单失败");
        }
    }


    /**
     * 删除系统菜单
     *
     * @param sysMenu
     * @return
     */
    @Transactional
    public ResultData delSysMenu(SysMenu sysMenu) {
        if (StringUtils.isEmpty(sysMenu.getId())) {
            return ResultData.createFail("id不能为空");
        }
        if (sysMenu.getId().equals("0")) {
            return ResultData.createFail("系统菜单不能删除");
        }
        sysMenu.setDel(StringConstant.DEL_OK);
        log.info("删除系统菜单:" + JSON.toJSONString(sysMenu));
        int i = sysMenuMapper.deleteSysMenu(sysMenu);
        if (i > 0) {
            return ResultData.createSuccess(null);
        } else {
            return ResultData.createFail("删除系统菜单失败");
        }
    }

    /**
     * 查询父菜单下面的子菜单
     *
     * @param parentId
     * @return
     */
    public ResultData<List<ZTreeVo>> getSysMenuByParentId(String parentId) {
        //首先创建一个集合
        List<ZTreeVo> list = new ArrayList<>();
        //创建sysMenu对象
        SysMenu sysMenu = new SysMenu();
        //传入值 （del==0 && 放入父菜单id）
        sysMenu.setDel(StringConstant.DEL_NO);
        sysMenu.setParentId(parentId);
        //在创建一个对象
        SysMenu allMenu = new SysMenu();
        //这个对象里面只塞入一个属性，就是del==0，也就是删除状态为0的
        allMenu.setDel(StringConstant.DEL_NO);
        //将所有未删除的菜单放入allMenuList集合当中
        List<SysMenu> allMenuList = sysMenuMapper.getSysMenuList(allMenu);
        //根据父id查询到的菜单放入集合当中
        List<SysMenu> sysMenuList = sysMenuMapper.getSysMenuList(sysMenu);
        //将根据父id查询到的菜单集合遍历出来
        for (SysMenu menu : sysMenuList) {
            //并且传入参数  寻找第一级菜单
            ZTreeVo zTreeVo = new ZTreeVo();
            zTreeVo.setId(menu.getId());
            zTreeVo.setOpen(true);
            zTreeVo.setName(menu.getMenuName());

            //递归:方法体内调用自身方法  getChildMenu(需要传入两个参数  在全部的菜单当中根据指定的id进行查询菜单)
            //往下继续寻找子子菜单  是调用getChildMenu的方法  根据当前的id查询父id为当前id的菜单
            List<SysMenu> chid = getChildMenu(menu.getId(), allMenuList);
            //zTreeVo里面的属性Children则是该菜单下的子菜单
            zTreeVo.setChildren(getZTree(chid, allMenuList));
            list.add(zTreeVo);
        }
        return ResultData.successData("查询成功 ", list);
    }

    /**
     * @param chid
     * @param allMenu
     * @return
     */
    public List<ZTreeVo> getZTree(List<SysMenu> chid, List<SysMenu> allMenu) {
        //首先创建一个ZTreeVo类型的集合
        List<ZTreeVo> zTreeVoChildList = new ArrayList<>();
        //并且循环遍历出来
        for (SysMenu childMenuItem : chid) {
            ZTreeVo zTreeVo = new ZTreeVo();
            zTreeVo.setId(childMenuItem.getId());
            zTreeVo.setOpen(true);
            zTreeVo.setName(childMenuItem.getMenuName());
            //自菜单的话，就是调用getChildZTree这个方法  传入parentId父id  和  allMenu所有的菜单进行查询
            zTreeVo.setChildren(getChildZTree(childMenuItem.getId(), allMenu));
            //将zTreeVo这个对象放入zTreeVoChildList集合中
            zTreeVoChildList.add(zTreeVo);
        }
        return zTreeVoChildList;
    }

    /**
     * getChildZTree这个方法  首先传递两个参数，parentId父id  和  allMenu所有的菜单
     *
     * @param parentId
     * @param allMenu
     * @return
     */
    public List<ZTreeVo> getChildZTree(String parentId, List<SysMenu> allMenu) {
        //创建一个集合
        List<ZTreeVo> zTreeVoChildList = new ArrayList<>();
        //调用getChildMenu的方法  根据父id在所有的菜单中查询  返回chidMenu集合对象
        List<SysMenu> chidMenu = getChildMenu(parentId, allMenu);
        //循环遍历出来
        for (SysMenu chidMenuItem : chidMenu) {
            ZTreeVo chidZTreeVo = new ZTreeVo();
            chidZTreeVo.setId(chidMenuItem.getId());
            chidZTreeVo.setOpen(true);
            chidZTreeVo.setName(chidMenuItem.getMenuName());
            //运用到递归  方法内调用自身方法
            chidZTreeVo.setChildren(getChildZTree(chidMenuItem.getId(), allMenu));
            zTreeVoChildList.add(chidZTreeVo);
        }
        return zTreeVoChildList;
    }

    /**
     * 查询指定id菜单下的子菜单  如果父id等于id那么就显示出来
     * 传入2个值，第一个是传入id   第二个查询所有的菜单
     *
     * @param id
     * @param allMenuList
     * @return
     */
    public List<SysMenu> getChildMenu(String id, List<SysMenu> allMenuList) {
        //首先创建一个集合
        List<SysMenu> sysMenus = new ArrayList<>();
        //并且将所有菜单集合循环遍历出来
        for (SysMenu sysMenu : allMenuList) {
            //如果我们查询的id就是父菜单id，那么我们查询的就没有错   并且父菜单id不能为空
            if (sysMenu.getParentId() != null && sysMenu.getParentId().equals(id)) {
                //将sysMenu放入集合当中
                sysMenus.add(sysMenu);
            }
        }
        //返回的是一个sysMenus集合
        return sysMenus;
    }
}
